package com.max.common.util;

import java.io.File;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

/**
 * 
 * 项目名称:max-project-graphics
 * 文件名称:XMLConfig.java
 * 文件描述:
 * 创建人员:chenyibo
 * 创建时间:2013-1-28 下午05:32:26
 * 修改人员:chenyibo
 * 修改时间:2013-1-28 下午05:32:26
 * 修改备注:
 * @version V1.0
 */
public class XMLConfig
{

    private Document doc;

    private StringTokenizer st;

    public XMLConfig(Document doc)
    {
    	this.doc = doc;
    }
    

    public static synchronized XMLConfig getInstance(String xmlContent)
    {
    	XMLConfig config = null;
    	
    	try
    	{
    		StringReader sr = new StringReader(xmlContent);
    		DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    		Document doc = builder.parse(new InputSource(sr));
    		
    		config = new XMLConfig(doc);
    	}
    	catch(Exception e)
    	{
    		e.printStackTrace();
    	}
    	
    	return config;
    }
    
    public static synchronized XMLConfig getInstance(File file)
    {
    	XMLConfig config = null;
    	
        try
        {
        	DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        	DocumentBuilder builder = factory.newDocumentBuilder();
        	Document doc = builder.parse(file);
        	
        	config = new XMLConfig(doc);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        
        return config;
    }
    
    
    
    /**
     * 
     * @param nodePath
     * @param key
     * @return
     */
    public Map<String,Map<String,String>> getAllValues(String nodePath, String key)
    {
        Map<String,Map<String,String>> parentMap = new HashMap<String,Map<String,String>>(4);
        List<Node> nodeList = findNodes(nodePath);
        
        if(nodeList != null && key != null && !key.equals(""))
        {
            for(Node node:nodeList)
            {
                String childKey = null;
            	Map<String,String> map = new HashMap<String,String>(4);
            	
            	/**取ELEMENT_NODE*/
                NodeList childNodes = node.getChildNodes();
                for(int j = 0; j < childNodes.getLength(); j++)
                {
                    Node childNode = childNodes.item(j);
                    
                    if((childNode.getNodeType() == Node.ELEMENT_NODE && childNode.hasChildNodes())
                    		|| childNode.getNodeType() == Node.ATTRIBUTE_NODE)
                    {
                    	String childName = childNode.getNodeName();
                    	String childValue = childNode.getFirstChild().getNodeValue();
                        map.put(childName, childValue);
                        
//                        if(key.equals(childName))
//                        	childKey = childValue;
                    }
                }

                /**取ATTRIBUTE_NODE*/
                NamedNodeMap nodeMap = node.getAttributes();
                for(int j = 0; j < nodeMap.getLength(); j++)
                {
                	Node attrNode = nodeMap.item(j);
                	
                	if(attrNode.getNodeType() == Node.ATTRIBUTE_NODE)
                	{
                		String attrName = attrNode.getNodeName();
                    	String attrValue = attrNode.getNodeValue();
                    	map.put(attrName, attrValue);
                    	
//                    	if(key.equals(attrName))
//                        	childKey = attrValue;
                	}
                }
                
                if(map.containsKey(key))
                	parentMap.put(map.get(key), map);
                
//                if(childKey != null)
//                {
//                    parentMap.put(childKey, map);
//                    childKey = null;
//                }
            }
        }
        
        return parentMap;
    }
    
    
    public List<Node> findNodes(String nodePath)
    {
        List<Node> nodes = new ArrayList<Node>(8);
        
        if(doc == null)
        	return nodes;
        
        Element root = doc.getDocumentElement();
        
        if(nodePath != null && !nodePath.equals(""))
        {
            Node ancestor = root;
            st = new StringTokenizer(nodePath, "/");
            String nodeName = st.nextToken();
            
            if(ancestor.getNodeName().equals(nodeName))
            {
                nodes.add(ancestor);
                
                if(st.hasMoreTokens())
                	nodes = findChildNodes(nodes, st.nextToken());
            }
        }
        
        return nodes;
    }
    
    
    private List<Node> findChildNodes(List<Node> nodesList, String nodeName)
    {
        List<Node> chileNodesList = new ArrayList<Node>(8);
        
        for(int i = 0; i < nodesList.size(); i++)
        {
            Node parentNode = nodesList.get(i);
            
            if(parentNode.getNodeType() != 1)
            	continue;
            
            NodeList nl = parentNode.getChildNodes();
            
            for(int j = 0; j < nl.getLength(); j++)
            {
                Node childNode = nl.item(j);
                
                if(childNode.getNodeName().equals(nodeName))
                	chileNodesList.add(childNode);
            }
        }

        if(st.hasMoreTokens())
        	chileNodesList = findChildNodes(chileNodesList, st.nextToken());
        
        return chileNodesList;
    }
}
